#include <linux/init.h>
#include <linux/module.h>
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/kobject.h>

#include <linux/sysfs.h>


// 自定义kobj
struct mykobj {
    struct kobject kobj;
    int value1;
    int value2;
};


struct mykobj *mykobject01;


 //定义kobject的释放函数
static void dynamic_kobj_release(struct kobject *kobj)
{
    struct mykobj *mykobj = container_of(kobj, struct mykobj, kobj);
    printk(KERN_EMERG "%s: kobj(%s)[%p]\n",__func__, kobject_name(kobj), kobj);
    
    kfree(mykobj);
}







// // 定义kobject 属性项
// struct attribute value1 = {
//     .name = "value1",
//     .mode = 0666,
// };

// struct attribute value2 = {
//     .name = "value2",
//     .mode = 0666,
// };

ssize_t show_myvalue1(struct kobject *kobj, struct kobj_attribute *attr,
			char *buf)
{
    ssize_t count;
    count = sprintf(buf, "show_myvalue1\n");

    return count;
}

ssize_t store_myvalue1(struct kobject *kobj, struct kobj_attribute *attr,
            const char *buf, size_t count)
{
    printk(KERN_EMERG "store_myvalue1 buf is :%s\n", buf);
    return count;
}

ssize_t show_myvalue2(struct kobject *kobj, struct kobj_attribute *attr,
			char *buf)
{
    ssize_t count;
    count = sprintf(buf, "show_myvalue2\n");

    return count;
}

ssize_t store_myvalue2(struct kobject *kobj, struct kobj_attribute *attr,
            const char *buf, size_t count)
{
    printk(KERN_EMERG "store_myvalue2 buf is :%s\n", buf);
    return count;
}



struct kobj_attribute value1 = __ATTR(value1, 0664, show_myvalue1, store_myvalue1);
struct kobj_attribute value2 = __ATTR(value2, 0664, show_myvalue2, store_myvalue2);

static struct attribute *myattr[] = {
    &value1.attr,
    &value2.attr,
    NULL,
};


ssize_t	myshow(struct kobject *kobj, struct attribute *attr, char *buf)
{
    ssize_t count;
    struct kobj_attribute *kobj_attr = container_of(attr, struct kobj_attribute, attr);
    
    count = kobj_attr->show(kobj, kobj_attr, buf);

    return count;
}

ssize_t	mystore(struct kobject *kobj, struct attribute *attr, const char *buf, size_t size)
{
    struct kobj_attribute *kobj_attr = container_of(attr, struct kobj_attribute, attr);


    return kobj_attr->store(kobj, kobj_attr, buf, size);
}

static struct sysfs_ops mysysfs_ops = {
    .show = myshow,
    .store = mystore,
};

// //定义了一个kobj_type结构体变量, 用于描述kobject类型
struct kobj_type mykobj_type = {
    .release = dynamic_kobj_release,
    .default_attrs = myattr,
    .sysfs_ops = &mysysfs_ops
};




static int __init mykobject_init(void)
{   
    int ret;
    printk(KERN_EMERG "mykobject_init OK!\n");

    // 创建自定义的kobj
    mykobject01 = kzalloc(sizeof(struct mykobj), GFP_KERNEL);
    mykobject01->value1 = 1;
    mykobject01->value2 = 1;
    
    ret = kobject_init_and_add(&mykobject01->kobj, &mykobj_type, NULL, "%s", "mykobject01");

    return 0;
}



static void __exit mykojbect_exit(void)
{

    kobject_put(&mykobject01->kobj);
    printk(KERN_EMERG "mykojbect_exit OK!\n");  
}



module_init(mykobject_init);
module_exit(mykojbect_exit);

MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Treasure1029");
